function DestroyShotGunReloadTimer takes timer reloadTimer returns nothing
	local integer timerId = GetHandleId(reloadTimer)
	local unit gunner = LoadUnitHandle(udg_HT , timerId , 3)
	local item gun = LoadItemHandle(udg_HT , timerId , 4)
	local item bullet = LoadItemHandle(udg_HT , timerId , 5)
	//--
	call PauseTimer(reloadTimer)
	call FlushChildHashtable(udg_HT , timerId)
	call DestroyTimer(reloadTimer)
	call SetItemDroppable(gun , true)
	call SetItemDroppable(bullet , true)
	call SaveBoolean(udg_UnitDataHashTable , GetHandleId(gunner) , StringHash("RELOADING") , false)
	call SaveTimerHandle(udg_UnitDataHashTable , GetHandleId(gunner) , StringHash("RELOAD_SHOT_GUN_TIMER") , null)
endfunction

function ReloadingShotGun takes nothing returns nothing
	local timer reloadTimer = GetExpiredTimer()
	local integer timerId = GetHandleId(reloadTimer)
	local unit gunner = LoadUnitHandle(udg_HT , timerId , 3)
	local item gun = LoadItemHandle(udg_HT , timerId , 4)
	local item bullet = LoadItemHandle(udg_HT , timerId , 5)
	//--
	if gun != null and bullet != null and UnitHasItem(gunner , gun) and UnitHasItem(gunner , bullet) and GetItemCharges(gun) < 8 and GetItemCharges(bullet) >= 1 then
		call SetItemCharges(gun , GetItemCharges(gun) + 1)
		call SetItemCharges(bullet , GetItemCharges(bullet) - 1)
		if GetItemCharges(bullet) <= 0 then
			call RemoveItem(bullet)
		endif
		call PlaySoundOnUnit(gunner , "clipin.wav")
	endif
	
	if GetItemCharges(gun) < 8 then
		if GetItemCharges(bullet) <= 0 then
			set bullet = GetItemOfTypeFromUnitBJ(gunner , 'I00Q')
			if bullet == null then
				call DestroyShotGunReloadTimer(reloadTimer)
			else
				call SetItemDroppable(bullet , false)
				call SaveItemHandle(udg_HT , timerId , 5 , bullet)
			endif
		else
			call SetItemDroppable(bullet , false)
			call SaveItemHandle(udg_HT , timerId , 5 , bullet)
		endif
	else
		call DestroyShotGunReloadTimer(reloadTimer)
	endif
	
	//--
	set reloadTimer = null
	set gunner = null
	set gun = null
	set bullet = null
endfunction

function ReloadShotGun takes unit gunner returns nothing
	local item gun = GetItemOfTypeFromUnitBJ(gunner , 'I00P')
	local item bullet = GetItemOfTypeFromUnitBJ(gunner , 'I00Q')
	local player gunnerOwner = GetOwningPlayer(gunner)
	local boolean reloading = LoadBoolean(udg_UnitDataHashTable , GetHandleId(gunner) , StringHash("RELOADING"))
	local timer reloadTimer = LoadTimerHandle(udg_UnitDataHashTable , GetHandleId(gunner) , StringHash("RELOAD_SHOT_GUN_TIMER"))
	local integer timerId = 0
	//--
	if gun != null and bullet != null and not reloading and reloadTimer == null and GetItemCharges(gun) < 8 then
		call SetItemDroppable(gun , false)
		call SetItemDroppable(bullet , false)
		call SaveBoolean(udg_UnitDataHashTable , GetHandleId(gunner) , StringHash("RELOADING") , true)
		set reloadTimer = CreateTimer()
		call SaveTimerHandle(udg_UnitDataHashTable , GetHandleId(gunner) , StringHash("RELOAD_SHOT_GUN_TIMER") , reloadTimer)
		set timerId = GetHandleId(reloadTimer)
		call SaveUnitHandle(udg_HT , timerId , 3 , gunner)
		call SaveItemHandle(udg_HT , timerId , 4 , gun)
		call SaveItemHandle(udg_HT , timerId , 5 , bullet)
		call TimerStart(reloadTimer , 0.8 , true , function ReloadingShotGun)
		call DisplayTimedTextToPlayer(gunnerOwner , 0 , 0 , 2.0 , "裝填彈藥中")
		call PlaySoundOnUnit(gunner , "clipout.wav")
	endif
	//--
	set gun = null
	set bullet = null
	set gunnerOwner = null
	set reloadTimer = null
endfunction

function ShotGunTry takes nothing returns nothing
	local unit gunner = GetTriggerUnit()
	local integer gunnerId = GetHandleId(gunner)
	local player gunnerOwner = GetOwningPlayer(gunner)
	local item gun = GetItemOfTypeFromUnitBJ(gunner , 'I00P')
	local integer gunCharge = GetItemCharges(gun)
	local item bullet = GetItemOfTypeFromUnitBJ(gunner , 'I00Q')
	local boolean reloading = LoadBoolean(udg_UnitDataHashTable , gunnerId , StringHash("RELOADING"))
	//--	
	if gun == null then
		call UnitRemoveAbility(gunner , 'A01L')
	elseif gunCharge <= 0 then
		call IssueImmediateOrderById(gunner , 851972) //停止
		if bullet == null then
			call DisplayTimedTextToPlayer(gunnerOwner, 0 , 0 , 2.0 , "沒彈藥了")
		else
			call DisplayTimedTextToPlayer(gunnerOwner, 0 , 0 , 1.0 , "裝填彈藥中")
			if not reloading then
				call ReloadShotGun(gunner)
			endif
		endif
	endif
	//--
	set gunner = null
	set gunnerOwner = null
	set gun = null
	set bullet = null
endfunction

function ShotGun_Try takes nothing returns nothing
	if GetSpellAbilityId() == 'A01L' then
		call ShotGunTry()
	endif
endfunction

//--開火
function ShotGunBulletDamage takes nothing returns nothing
	local unit target = GetEnumUnit()
	//--
	if IsUnitEnemy(target , udg_TempPlayer) and IsUnitInRangeLoc(target , udg_TempLocation , udg_TempRadius) and not IsUnitType(target , UNIT_TYPE_STRUCTURE) and GetUnitState(target , UNIT_STATE_LIFE) > 0.0 and not HaveSavedBoolean(udg_TempHashTable , GetHandleId(target) , 3) then
		call UnitDamageTarget(udg_TempDamager , target , udg_TempDamage , true , false , ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD , WEAPON_TYPE_METAL_MEDIUM_BASH)
		set udg_TempBoolean = true
	endif
	//--
	set target = null
endfunction

function ShotGunBulletRoutine takes nothing returns nothing
	local timer bulletTimer = GetExpiredTimer()
	local integer timerId = GetHandleId(bulletTimer)
	local unit bulletEffect = LoadUnitHandle(udg_HT , timerId , 3)
	local real dx = LoadReal(udg_HT , timerId , 4)
	local real dy = LoadReal(udg_HT , timerId , 5)
	local real process = LoadReal(udg_HT , timerId , 6)
	//--
	//造成傷害
	set udg_TempDamager = bulletEffect
	set udg_TempPlayer = GetOwningPlayer(bulletEffect)
	set udg_TempDamage = 20.0
	set udg_TempRadius = 50.0
	set udg_TempLocation = GetUnitLoc(bulletEffect)
	set udg_TempBoolean = false
	set bj_wantDestroyGroup = true
	call ForGroupBJ(GetUnitsInRangeOfLocMatching(udg_TempRadius+70.0, udg_TempLocation , null) , function ShotGunBulletDamage)
	call RemoveLocation(udg_TempLocation)
	//移動子彈
	if udg_TempBoolean or process > 50.0 then
		call PauseTimer(bulletTimer)
		call FlushChildHashtable(udg_HT , timerId)
		call DestroyTimer(bulletTimer)
		call KillUnit(bulletEffect)
		call RemoveUnit(bulletEffect)
	else
		set process = process + 1.0
		call SaveReal(udg_HT , timerId , 6 , process)
		call SetUnitX(bulletEffect , GetUnitX(bulletEffect) + dx)
		call SetUnitY(bulletEffect , GetUnitY(bulletEffect) + dy)
	endif
	//--
	set bulletTimer = null
	set bulletEffect = null
endfunction

function ShotGunFire takes nothing returns nothing
	local unit gunner = GetTriggerUnit()
	local player gunnerOwner = GetOwningPlayer(gunner)
	local location gunnerLocation = GetUnitLoc(gunner)
	local location targetLocation = GetSpellTargetLoc()
	local item gun = GetItemOfTypeFromUnitBJ(gunner , 'I00P')
	local real angle = 0.0
	local real delta = 2500.0 * 0.01 // speed setting
	local real dx = 0.0
	local real dy = 0.0
	local unit bulletEffect = null
	local timer bulletTimer = null
	local integer timerId = 0
	local integer whichBullet = 0
	//--
	call SetItemCharges(gun , GetItemCharges(gun) - 1)
	call DestroyShotGunReloadTimer(LoadTimerHandle(udg_UnitDataHashTable , GetHandleId(gunner) , StringHash("RELOAD_SHOT_GUN_TIMER")))
	loop
	exitwhen whichBullet >= 5
		set angle = AngleBetweenPoints(gunnerLocation , targetLocation) + GetRandomReal(-15.0 , 15.0)
		set dx = Cos(angle * bj_DEGTORAD) * delta
		set dy = Sin(angle * bj_DEGTORAD) * delta
		set bulletEffect = CreateUnit(gunnerOwner , 'e003' , GetLocationX(gunnerLocation) , GetLocationY(gunnerLocation) , angle)
		set bulletTimer = CreateTimer()
		set timerId = GetHandleId(bulletTimer)
		call SetUnitX(bulletEffect , GetLocationX(gunnerLocation) + dx)
		call SetUnitY(bulletEffect , GetLocationY(gunnerLocation) + dy)	
		call SaveUnitHandle(udg_HT , timerId , 3 , bulletEffect)
		call SaveReal(udg_HT , timerId , 4 , dx)
		call SaveReal(udg_HT , timerId , 5 , dy)
		call SaveReal(udg_HT , timerId , 6 , 0.0)
		call TimerStart(bulletTimer , 0.01 , true , function ShotGunBulletRoutine)
	set whichBullet = whichBullet + 1
	endloop
	if GetItemCharges(gun) <= 0 then
		call ReloadShotGun(gunner)
	endif
	//聲音
	call PlaySoundOnUnit(gunner , "Units\\Human\\Rifleman\\RiflemanAttack1.wav")
	call UnitPlayAnimation(gunner , 149 , 2.0 , 0.4)
	//--
	set gunner = null
	set gunnerOwner = null
	call RemoveLocation(gunnerLocation)
	set gunnerLocation = null
	call RemoveLocation(targetLocation)
	set targetLocation = null
	set gun = null
	set bulletEffect = null
	set bulletTimer = null
endfunction

function ShotGun_Fire takes nothing returns nothing
	if GetSpellAbilityId() == 'A01L' then
		call ShotGunFire()
	endif
endfunction

function InitTrig_ShotGun takes nothing returns nothing
	local trigger shotGunFire = CreateTrigger()
	set gg_trg_ShotGun = CreateTrigger()
	call TriggerRegisterPlayerForceUnitEvent(gg_trg_ShotGun , EVENT_PLAYER_UNIT_SPELL_CHANNEL)
	call TriggerAddAction(gg_trg_ShotGun , function ShotGun_Try)
	
	call TriggerRegisterPlayerForceUnitEvent(shotGunFire , EVENT_PLAYER_UNIT_SPELL_EFFECT)
	call TriggerAddAction(shotGunFire , function ShotGun_Fire)
endfunction

